package com.qilin.hammer.util;

import java.io.StringReader;
import java.util.ArrayList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import jxl.common.Logger;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

public class XMLHelper {

	private Document expect_doc;
	private Document check_doc;
	private static Logger logger = Logger.getLogger(XMLHelper.class);
	
	public XMLHelper(String expect_xml, String check_xml) throws Exception{
		this.init(expect_xml, check_xml);
	}
	
	private void init(String expect_xml, String check_xml) throws Exception{
	    try {
	        DocumentBuilderFactory domFactory =
	            DocumentBuilderFactory.newInstance();
	        DocumentBuilder domBuilder = domFactory.newDocumentBuilder();
	        InputSource is1 = new InputSource(new StringReader(expect_xml));
	        expect_doc = domBuilder.parse(is1);
	        InputSource is2 = new InputSource(new StringReader(check_xml));
	        check_doc = domBuilder.parse(is2);
	    } catch (Exception e) {
	        logger.error("Fail to parse xml");
	        e.printStackTrace();
	        throw e;
	    }
	}
	
	public void getNodeValues(ArrayList<String> values, Node node, String path) throws Exception{
		if(!path.startsWith("/"))
			throw new Exception("Path must start with '/': "+path);
		int pos = path.indexOf("/", 1);
		String tag;
		if(pos == -1){
			tag = path.substring(1);			
		} else {
			tag = path.substring(1, pos);
			path = path.substring(pos);
		}
		NodeList subnodes = node.getChildNodes();
		if(subnodes.getLength() == 0){
			logger.warn("Tag can't be found in the path: "+tag);
		} else {		    
			int count = 0;
			for(int i=0; i<subnodes.getLength(); i++){
				Node subnode = subnodes.item(i);
				if(subnode.getNodeName().equals(tag)){
					count++;
					if(pos == -1){
					    String value = subnode.getNodeValue();
					    if(value != null){
					    	logger.warn(tag + " is not a text node");
					    }else{
					    	NodeList textnodes = subnode.getChildNodes();
					    	for(int j=0; j<textnodes.getLength(); j++){
					    		Node textNode = textnodes.item(j);
					    		values.add(textNode.getNodeValue());
					    	}
					    }
					} else {
						getNodeValues(values, subnode, path);
					}
				}
			}
			if(count == 0){
				logger.warn("Tag can't be found in the path: "+tag);
			}
		}
		
	}
	
	public boolean verifyByPath(String path){
		ArrayList<String> expect_values = new ArrayList<String>();
		try {
			this.getNodeValues(expect_values, expect_doc, path);
			System.out.println(expect_values);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return true;
	}
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		String expect_xml = "<RecordCollection>"+
"<Record><Name>B</Name><Value>7200</Value></Record>"+
"<Record><Name>C</Name><Value>7200</Value></Record>"+
"<Record><Name>D</Name><Value>7200</Value></Record>"+
"<Record><Name>End</Name><Value>7200</Value></Record>"+
"<Record><Name>A</Name><Value>0</Value></Record>"+
"</RecordCollection>";
		XMLHelper xmlhelper = null;
		try {
			xmlhelper = new XMLHelper(expect_xml, expect_xml);
		} catch (Exception e) {
			e.printStackTrace();
		}
		xmlhelper.verifyByPath("/RecordCollection/Record/Value");
	}

}
